/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.nanosn.coffeemaker.datebase.api;

import java.lang.reflect.Field;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;

/**
 *
 * @author selkhateeb
 */
public abstract class Controller<Entity> {

    private EntityManager entityManager;

    public Controller(EntityManagerFactory emf) {
        this.entityManager = emf.createEntityManager();
    }

    public Controller() {
        this.entityManager = EMF.get().createEntityManager();
    }

    protected String Query(Class<Entity> clazz, Object entity) {
        String query = null;
        try {
            query = "SELECT e FROM " + clazz.getSimpleName() + " e WHERE ";
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true);
                if (field.get(entity) == null) {
                    continue;
                }
                query += "e." + field.getName() + "= :" + field.getName();
                query += field.get(entity);
            }
        }
        catch (IllegalArgumentException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null,
                                                             ex);
        }
        catch (IllegalAccessException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null,
                                                             ex);
        }

        return query;
    }

    @Override
    protected void finalize() throws Throwable {
        close();
    }

    public List<Entity> Query(int start, int max, String query) {

        Query q = entityManager.createQuery(query);

        if (max > 0) {
            q.setMaxResults(max);
        }
        q.setFirstResult(start);
        return q.getResultList();
    }
//    public Entity Query(Query query) {
//        return (Entity)query.getSingleResult();
//    }

    public List<Entity> Query(String query) {
        return this.Query(0, 0, query);
    }

    protected void _persist(Entity entity) {
        entityManager.getTransaction().begin();
        entityManager.persist(entity);
        entityManager.getTransaction().commit();
    }

    public final void remove(Entity entity) {
        entityManager.getTransaction().begin();
        entityManager.remove(entityManager.merge(entity));
        entityManager.getTransaction().commit();
    }

    public final Entity merge(Entity entity) {

        entityManager.getTransaction().begin();
        Entity e = entityManager.merge(entity);
        entityManager.getTransaction().commit();
        return e;

    }

    public Entity find(Class<Entity> clazz, Object primaryKey) {
        return entityManager.find(clazz, primaryKey);
    }

    public void close() {
        entityManager.close();
    }
}
